var OPENLOGFLAG = true;
var MAX_KEY_LEN = 100;
var debug_mode = true;
var InternalLog = {};

function _formatTime(t){
    return t < 10 ? "0" + t : "" + t;
};
 
function _timeStamp(){
    var t = new Date();
    //such as "[2014-01-25 08:13:01] "  
    var str = "[" + t.getFullYear() + "-" + _formatTime(t.getMonth()+1) + "-" + _formatTime(t.getDate()) + " ";
    str += _formatTime(t.getHours()) + ":" + _formatTime(t.getMinutes()) + ":" + _formatTime(t.getSeconds()) + "] ";
    return str;
};

function _tojson(obj){
    if (!debug_mode) {
        if (obj instanceof Array && obj.length > MAX_KEY_LEN) {         
           return "array length is too long!";
        }
    }
    if(obj instanceof Error) {
       obj = obj.stack;
    }  
    if (typeof obj === "string") {
       return obj;
    }
    else if (typeof obj === "function") {
       return "[ Function ]";
    }
    else if (typeof obj === "number") {
       return ""+obj;
    }
    else if (typeof obj === "boolean") {
       return obj ? "true" : "false";
    }
    else
    {
       if (obj === null) {
          return "null";
       }
       if (obj === undefined) {
          return "undefined";
       }
       if (obj instanceof RegExp) {
          return obj.toString();
       }
    }
    
    try {
        var cache = [];
        var last = null;
        var len = 0;   
        return JSON.stringify(obj, function(key, value){
            if (!debug_mode) {
                len++;
                if (len > MAX_KEY_LEN) {
                    throw new Error("object is too big!");
                }
            }
            if(last !== this) {
                if(cache.indexOf(this) > -1) {
                    cache.pop();	
                }  
                else {
                    cache.push(this);
                }
                last = this;
            }
            if(value && typeof value === "object") {
                var index = cache.indexOf(value);
                if(index > -1)
                    return "[ Circular " + index + " ]";
            }
            return value;
        });
    }
    catch(e) {
       return e.toString();  
    }
};

InternalLog.filter = function(msg){
    var str;
    if (arguments.length > 1 && typeof msg === "string") {
        var len = arguments.length;
        var index = 1;
        var t_args = arguments;  
        str = msg.replace(/%[j%]/g, function(x) {
            if (x === "%%") return "%";
            if (index >= len) return x;  
            return _tojson(t_args[index++]);
        });   
    }
    else {
        str = _tojson(msg);
    }
    return str;
 };

InternalLog.stack = function () {
    var e = new Error();
    var lines = e.stack.split("\n");
    lines.shift();
    var line = lines[2];
    line = line.substring(7);
    var _line1 = line.split(" ");
    if (_line1.length === 1) 
        return "(" + _line1[0] + ") ";
    else
        return "" + _line1[1] + " ";
    /*
    var _line2 = _line1[0];
    if (_line2) {
        var _split1 = _line2.split(".");
        if (_split1.length === 2) {
            var _line3 = _line1[1];
            var _split2 = _line3.split(":");
            if (_split2.length === 3) {
                var _codeLine = Number(_split2[1]);
                return ("(" + _split1[0] + ".js " + _split1[1] + " " + _codeLine + ") ");
            }
        }
    }
    */
    return "";
};

InternalLog.log = function(type) {
    var _log = console.log || cc.log;
    try {
        var slice_i = 1;
        if (arguments.length < 2 || type.match(/%j/)) {        
            slice_i = 0;
        }
        var str = InternalLog.filter.apply(InternalLog, Array.prototype.slice.call(arguments, slice_i));
        if(OPENLOGFLAG){
            _log.call(InternalLog, "%s%s" + str, _timeStamp(), InternalLog.stack());
        }
    }
    catch(e) {
        _log("log internal err : " + e);
    }
};

InternalLog.info = function () {
    
};

InternalLog.warn = function(){
    
};

InternalLog.err = function(){
    
};

module.exports = InternalLog;
